//! # 错误处理策略模块
//!
//! 提供统一的错误处理框架和策略组合

use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::time::Duration;
use crate::{ResilienceResult, DeadLetterQueue, RetryStrategy};

/// 错误处理策略
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ErrorHandlingStrategy {
    /// 重试策略
    Retry {
        max_attempts: u32,
        backoff: BackoffStrategy,
    },
    /// 死信队列策略
    DeadLetter {
        dlq_topic: String,
    },
    /// 跳过错误
    Skip,
    /// 中止处理
    Abort,
    /// 自定义处理器
    Custom {
        handler_name: String,
    },
    /// 组合策略
    Composite {
        strategies: Vec<ErrorHandlingStrategy>,
    },
}

/// 退避策略
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BackoffStrategy {
    /// 固定延迟
    Fixed { delay_ms: u64 },
    /// 线性增长
    Linear { initial_delay_ms: u64, increment_ms: u64 },
    /// 指数退避
    Exponential { initial_delay_ms: u64, max_delay_ms: u64, multiplier: f64 },
}

/// 错误处理结果
#[derive(Debug, Clone)]
pub enum ErrorHandlingResult {
    /// 重试，指定延迟时间
    Retry { delay: Duration },
    /// 发送到死信队列
    SendToDeadLetter,
    /// 跳过此消息
    Skip,
    /// 中止处理流程
    Abort,
    /// 继续处理
    Continue,
}

/// 错误处理器接口
#[async_trait]
pub trait ErrorHandler: Send + Sync {
    /// 处理错误
    async fn handle_error(
        &self,
        error: &(dyn std::error::Error + Send + Sync),
        context: &ErrorContext,
    ) -> ResilienceResult<ErrorHandlingResult>;
    
    /// 获取处理器名称
    fn name(&self) -> &str;
    
    /// 是否支持此类型的错误
    fn supports_error(&self, error: &(dyn std::error::Error + Send + Sync)) -> bool {
        true // 默认支持所有错误
    }
}

/// 错误上下文
#[derive(Debug, Clone)]
pub struct ErrorContext {
    /// 错误发生的组件
    pub component: String,
    /// 当前重试次数
    pub retry_count: u32,
    /// 消息ID
    pub message_id: Option<String>,
    /// 主题
    pub topic: Option<String>,
    /// 额外属性
    pub attributes: std::collections::HashMap<String, String>,
}

/// 重试错误处理器
pub struct RetryErrorHandler {
    retry_strategy: Arc<dyn RetryStrategy>,
    name: String,
}

impl RetryErrorHandler {
    pub fn new(retry_strategy: Arc<dyn RetryStrategy>) -> Self {
        Self {
            retry_strategy,
            name: "retry_handler".to_string(),
        }
    }
    
    pub fn with_name(mut self, name: impl Into<String>) -> Self {
        self.name = name.into();
        self
    }
}

#[async_trait]
impl ErrorHandler for RetryErrorHandler {
    async fn handle_error(
        &self,
        error: &(dyn std::error::Error + Send + Sync),
        context: &ErrorContext,
    ) -> ResilienceResult<ErrorHandlingResult> {
        if self.retry_strategy.should_retry(context.retry_count, error) {
            let delay = self.retry_strategy.calculate_delay(context.retry_count);
            Ok(ErrorHandlingResult::Retry { delay })
        } else {
            Ok(ErrorHandlingResult::SendToDeadLetter)
        }
    }
    
    fn name(&self) -> &str {
        &self.name
    }
}

/// 死信队列错误处理器
pub struct DeadLetterErrorHandler {
    dead_letter_queue: Arc<dyn DeadLetterQueue>,
    name: String,
}

impl DeadLetterErrorHandler {
    pub fn new(dead_letter_queue: Arc<dyn DeadLetterQueue>) -> Self {
        Self {
            dead_letter_queue,
            name: "dead_letter_handler".to_string(),
        }
    }
    
    pub fn with_name(mut self, name: impl Into<String>) -> Self {
        self.name = name.into();
        self
    }
}

#[async_trait]
impl ErrorHandler for DeadLetterErrorHandler {
    async fn handle_error(
        &self,
        _error: &(dyn std::error::Error + Send + Sync),
        _context: &ErrorContext,
    ) -> ResilienceResult<ErrorHandlingResult> {
        // 直接发送到死信队列
        Ok(ErrorHandlingResult::SendToDeadLetter)
    }
    
    fn name(&self) -> &str {
        &self.name
    }
}

/// 跳过错误处理器
pub struct SkipErrorHandler {
    name: String,
}

impl SkipErrorHandler {
    pub fn new() -> Self {
        Self {
            name: "skip_handler".to_string(),
        }
    }
}

impl Default for SkipErrorHandler {
    fn default() -> Self {
        Self::new()
    }
}

#[async_trait]
impl ErrorHandler for SkipErrorHandler {
    async fn handle_error(
        &self,
        _error: &(dyn std::error::Error + Send + Sync),
        _context: &ErrorContext,
    ) -> ResilienceResult<ErrorHandlingResult> {
        Ok(ErrorHandlingResult::Skip)
    }
    
    fn name(&self) -> &str {
        &self.name
    }
}

/// 组合错误处理器
pub struct CompositeErrorHandler {
    handlers: Vec<Arc<dyn ErrorHandler>>,
    name: String,
}

impl CompositeErrorHandler {
    pub fn new() -> Self {
        Self {
            handlers: Vec::new(),
            name: "composite_handler".to_string(),
        }
    }
    
    pub fn add_handler(mut self, handler: Arc<dyn ErrorHandler>) -> Self {
        self.handlers.push(handler);
        self
    }
    
    pub fn with_name(mut self, name: impl Into<String>) -> Self {
        self.name = name.into();
        self
    }
}

impl Default for CompositeErrorHandler {
    fn default() -> Self {
        Self::new()
    }
}

#[async_trait]
impl ErrorHandler for CompositeErrorHandler {
    async fn handle_error(
        &self,
        error: &(dyn std::error::Error + Send + Sync),
        context: &ErrorContext,
    ) -> ResilienceResult<ErrorHandlingResult> {
        for handler in &self.handlers {
            if handler.supports_error(error) {
                let result = handler.handle_error(error, context).await?;
                
                // 如果不是 Continue，返回结果
                if !matches!(result, ErrorHandlingResult::Continue) {
                    return Ok(result);
                }
            }
        }
        
        // 所有处理器都返回 Continue，默认跳过
        Ok(ErrorHandlingResult::Skip)
    }
    
    fn name(&self) -> &str {
        &self.name
    }
}

/// 错误处理器工厂
pub struct ErrorHandlerFactory;

impl ErrorHandlerFactory {
    /// 创建重试处理器
    pub fn create_retry_handler(
        retry_strategy: Arc<dyn RetryStrategy>,
    ) -> Arc<dyn ErrorHandler> {
        Arc::new(RetryErrorHandler::new(retry_strategy))
    }
    
    /// 创建死信队列处理器
    pub fn create_dead_letter_handler(
        dead_letter_queue: Arc<dyn DeadLetterQueue>,
    ) -> Arc<dyn ErrorHandler> {
        Arc::new(DeadLetterErrorHandler::new(dead_letter_queue))
    }
    
    /// 创建跳过处理器
    pub fn create_skip_handler() -> Arc<dyn ErrorHandler> {
        Arc::new(SkipErrorHandler::new())
    }
    
    /// 创建组合处理器
    pub fn create_composite_handler(
        handlers: Vec<Arc<dyn ErrorHandler>>,
    ) -> Arc<dyn ErrorHandler> {
        let mut composite = CompositeErrorHandler::new();
        for handler in handlers {
            composite = composite.add_handler(handler);
        }
        Arc::new(composite)
    }
}

impl BackoffStrategy {
    /// 计算指定重试次数的延迟时间
    pub fn calculate_delay(&self, attempt: u32) -> Duration {
        let delay_ms = match self {
            Self::Fixed { delay_ms } => *delay_ms,
            Self::Linear { initial_delay_ms, increment_ms } => {
                initial_delay_ms + (increment_ms * attempt as u64)
            }
            Self::Exponential { initial_delay_ms, max_delay_ms, multiplier } => {
                let delay = (*initial_delay_ms as f64) * multiplier.powi(attempt as i32);
                delay.min(*max_delay_ms as f64) as u64
            }
        };
        
        Duration::from_millis(delay_ms)
    }
}

impl Default for ErrorContext {
    fn default() -> Self {
        Self {
            component: "unknown".to_string(),
            retry_count: 0,
            message_id: None,
            topic: None,
            attributes: std::collections::HashMap::new(),
        }
    }
}

/// 错误分类器
#[derive(Debug, Clone)]
pub enum ErrorClassification {
    /// 临时性错误（可重试）
    Transient,
    /// 永久性错误（不可重试）
    Permanent,
    /// 系统错误（需要特殊处理）
    System,
    /// 业务错误（业务逻辑错误）
    Business,
    /// 未知错误
    Unknown,
}

/// 错误分类器接口
pub trait ErrorClassifier: Send + Sync {
    /// 对错误进行分类
    fn classify(&self, error: &(dyn std::error::Error + Send + Sync)) -> ErrorClassification;
    
    /// 获取错误优先级
    fn get_priority(&self, error: &(dyn std::error::Error + Send + Sync)) -> u8 {
        5 // 默认中等优先级
    }
}

/// 默认错误分类器
pub struct DefaultErrorClassifier;

impl ErrorClassifier for DefaultErrorClassifier {
    fn classify(&self, error: &(dyn std::error::Error + Send + Sync)) -> ErrorClassification {
        let error_str = format!("{}", error);
        
        // 基本的错误分类逻辑
        if error_str.contains("timeout") || error_str.contains("connection") {
            ErrorClassification::Transient
        } else if error_str.contains("permission") || error_str.contains("unauthorized") {
            ErrorClassification::Permanent
        } else if error_str.contains("system") || error_str.contains("internal") {
            ErrorClassification::System
        } else if error_str.contains("validation") || error_str.contains("business") {
            ErrorClassification::Business
        } else {
            ErrorClassification::Unknown
        }
    }
}

/// 智能错误处理器
/// 根据错误分类自动选择处理策略
pub struct SmartErrorHandler {
    classifier: Box<dyn ErrorClassifier>,
    retry_handler: Arc<dyn ErrorHandler>,
    dead_letter_handler: Arc<dyn ErrorHandler>,
    skip_handler: Arc<dyn ErrorHandler>,
    name: String,
}

impl SmartErrorHandler {
    pub fn new(
        retry_handler: Arc<dyn ErrorHandler>,
        dead_letter_handler: Arc<dyn ErrorHandler>,
    ) -> Self {
        Self {
            classifier: Box::new(DefaultErrorClassifier),
            retry_handler,
            dead_letter_handler,
            skip_handler: Arc::new(SkipErrorHandler::new()),
            name: "smart_handler".to_string(),
        }
    }
    
    pub fn with_classifier(mut self, classifier: Box<dyn ErrorClassifier>) -> Self {
        self.classifier = classifier;
        self
    }
    
    pub fn with_name(mut self, name: impl Into<String>) -> Self {
        self.name = name.into();
        self
    }
}

#[async_trait]
impl ErrorHandler for SmartErrorHandler {
    async fn handle_error(
        &self,
        error: &(dyn std::error::Error + Send + Sync),
        context: &ErrorContext,
    ) -> ResilienceResult<ErrorHandlingResult> {
        let classification = self.classifier.classify(error);
        
        tracing::debug!(
            "错误分类: {:?}, 组件: {}, 重试次数: {}",
            classification, context.component, context.retry_count
        );
        
        match classification {
            ErrorClassification::Transient => {
                // 临时性错误先尝试重试
                let result = self.retry_handler.handle_error(error, context).await?;
                match result {
                    ErrorHandlingResult::Retry { .. } => Ok(result),
                    _ => {
                        // 重试失败，发送到死信队列
                        self.dead_letter_handler.handle_error(error, context).await
                    }
                }
            }
            ErrorClassification::Permanent => {
                // 永久性错误直接发送到死信队列
                self.dead_letter_handler.handle_error(error, context).await
            }
            ErrorClassification::System => {
                // 系统错误根据重试次数决定
                if context.retry_count < 2 {
                    self.retry_handler.handle_error(error, context).await
                } else {
                    self.dead_letter_handler.handle_error(error, context).await
                }
            }
            ErrorClassification::Business => {
                // 业务错误通常跳过
                self.skip_handler.handle_error(error, context).await
            }
            ErrorClassification::Unknown => {
                // 未知错误采用保守策略：重试一次，然后发送到死信队列
                if context.retry_count == 0 {
                    self.retry_handler.handle_error(error, context).await
                } else {
                    self.dead_letter_handler.handle_error(error, context).await
                }
            }
        }
    }
    
    fn name(&self) -> &str {
        &self.name
    }
}

/// 错误处理指标
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ErrorHandlingMetrics {
    /// 总错误数
    pub total_errors: u64,
    /// 重试成功数
    pub retry_success_count: u64,
    /// 重试失败数
    pub retry_failure_count: u64,
    /// 死信消息数
    pub dead_letter_count: u64,
    /// 跳过消息数
    pub skip_count: u64,
    /// 各类错误的统计
    pub error_classification_stats: std::collections::HashMap<String, u64>,
    /// 最后更新时间
    pub last_updated: chrono::DateTime<chrono::Utc>,
}

impl Default for ErrorHandlingMetrics {
    fn default() -> Self {
        Self {
            total_errors: 0,
            retry_success_count: 0,
            retry_failure_count: 0,
            dead_letter_count: 0,
            skip_count: 0,
            error_classification_stats: std::collections::HashMap::new(),
            last_updated: chrono::Utc::now(),
        }
    }
}

#[cfg(test)]
mod tests;

// 用于向后兼容的重新导出
pub use ErrorHandler as ErrorHandlerTrait;
pub use ErrorClassifier as ErrorClassifierTrait;